
#ifndef CT_GPIO_H
#define CT_GPIO_H

/*****************************************************************************
 * Included Files
 ****************************************************************************/
#include "ct_type.h"

#define CT_USE_PORT0
#define CT_USE_PORT1
// #define CT_USE_PORT2
// #define CT_USE_PORT3
// #define CT_USE_PORT4
// #define CT_USE_PORT5
// add more if necessary

/*****************************************************************************
 * Pre-processor Definitions
 ****************************************************************************/
/* GPIO PORT */
typedef enum {
    CT_GPIO_PORT0 = 0,
#ifdef CT_USE_PORT1
    CT_GPIO_PORT1,
#endif
#ifdef CT_USE_PORT2
    CT_GPIO_PORT2,
#endif
#ifdef CT_USE_PORT3
    CT_GPIO_PORT3,
#endif
#ifdef CT_USE_PORT4
    CT_GPIO_PORT4,
#endif
#ifdef CT_USE_PORT5
    CT_GPIO_PORT5,
#endif
} ct_gpio_port_t;

typedef enum {
    CT_GPIO_PIN_0    = ((ct_u8)0x01),
    CT_GPIO_PIN_1    = ((ct_u8)0x02),
    CT_GPIO_PIN_2    = ((ct_u8)0x04),
    CT_GPIO_PIN_3    = ((ct_u8)0x08),
    CT_GPIO_PIN_4    = ((ct_u8)0x10),
    CT_GPIO_PIN_5    = ((ct_u8)0x20),
    CT_GPIO_PIN_6    = ((ct_u8)0x40),
    CT_GPIO_PIN_7    = ((ct_u8)0x80),
    CT_GPIO_PIN_LNIB = ((ct_u8)0x0F),
    CT_GPIO_PIN_HNIB = ((ct_u8)0xF0),
    CT_GPIO_PIN_ALL  = ((ct_u8)0xFF)
} ct_gpio_pin_t;
/*****************************************************************************
 * Public Types
 ****************************************************************************/

/**
 * ct_gpio.h - GPIO Control
 *
 * This file contains the definitions for GPIO mode and interrupt types.
 */
typedef enum {
    CT_GPIO_MODE_QUASI = 0,   /** Dual-directional input/output */
    CT_GPIO_MODE_OUT_PP,      /** Push-pull output */
    CT_GPIO_MODE_INPUT,       /** Input */
    CT_GPIO_MODE_OUT_OD,      /** Open-drain output */
    CT_GPIO_MODE_INPUT_UP,    /** Input with pull-up */
    CT_GPIO_MODE_INPUT_DOWN,  /** Input with pull-down */
    CT_GPIO_MODE_ANALOG,      /** Analog input */
    CT_GPIO_MODE_OUT_PP_UP,   /** Push-pull output with pull-up */
    CT_GPIO_MODE_OUT_PP_DOWN, /** Push-pull output with pull-down */
    CT_GPIO_MODE_OUT_OD_UP,   /** Open-drain output with pull-up */
    CT_GPIO_MODE_OUT_OD_DOWN, /** Open-drain output with pull-down */
    CT_GPIO_MODE_AF_PP,       /** Push-pull alternate function */
    CT_GPIO_MODE_AF_OD,       /** Open-drain alternate function */
    CT_GPIO_MODE_AF_INPUT,    /** Input alternate function */
} ct_gpio_mode_t;

typedef enum {
    CT_GPIO_IRQ_LOW_LEVEL = 0, /** Low level */
    CT_GPIO_IRQ_HIGH_LEVEL,    /** High level */
    CT_GPIO_IRQ_FALLING_EDGE,  /** Falling edge */
    CT_GPIO_IRQ_RISING_EDGE,   /** Rising edge */
    CT_GPIO_IRQ_BOTH_EDGE,     /** Both rising and falling edges */
} ct_gpio_irq_trip_t;

typedef enum {
    //
    CT_GPIO_INPUT_TTL_MODE = 0, /**TTL Type       */
    CT_GPIO_INPUT_ST_MODE,      /** GPIO Schmitt Trig        */

} ct_gpio_Schmitt_t;

typedef enum {
    LEVEL = 0, /**Triple level  */
    EDGE,      /** */
} ct_gpio_irq_trip_mode_t;

typedef enum {
    CT_INT0 = 0,
    CT_INT1,
} ct_gpio_Int_t;

typedef enum {
    CT_GPIO_LOW = 0, /**< Low voltage level */
    CT_GPIO_HIGH,    /**< High voltage level */
    CT_GPIO_TOG,     /**< Toggle */
} ct_gpio_sta_t;

typedef struct {
    uint8_t        pin;
    ct_gpio_mode_t mode;
} ct_gpio_Init_t;

typedef struct {
    ct_gpio_port_t port;
    uint8_t        pin;
} ct_gpio_t;

#ifdef __cplusplus
extern "C" {
#endif
/*****************************************************************************
 * Public Function Prototypes
 ****************************************************************************/
/**
 * @brief  Initializes the specified GPIO pin.
 * @param[in] portx GPIO port
 * @param[in] set_pin GPIO pin and mode seting.
 * @return 0: Success, -1: Error
 * @note If use LIRC or LXT as Fsys need adjust this marco.
 */
char ct_gpio_Init(ct_gpio_port_t portx, ct_gpio_Init_t *set_pin);

/**
 * @brief  Set the mode of a specific GPIO pin.
 *
 * @param[in] portx  The GPIO port to which the pin belongs.
 * @param[in] PinMask   The specific pin on the GPIO port.
 * @param[in] mode   The mode to set for the pin (e.g., INPUT, OUTPUT, etc.).
 *
 * @return  None
 */
void ct_gpio_SetMode(ct_gpio_port_t portx,
                     uint8_t        PinMask,
                     ct_gpio_mode_t mode);

/**
 * @brief Reads the state of the specified GPIO pin.
 * @param portx GPIO port.
 * @param  PinMask GPIO pin.
 * @return ct_gpio_sta_t The state of the pin: CT_GPIO_HIGH or CT_GPIO_LOW.
 * @note If the pin is configured as an output, the read value may represent the output state of the pin.
 */
ct_gpio_sta_t ct_gpio_ReadPin(ct_gpio_port_t portx, uint8_t PinMask);

/**
 * @brief Write or toggle the state of a specified GPIO port and pin.
 *
 * @param[in] portx      GPIO port
 * @param[in] PinMask    GPIO pin
 * @param[in] state      Desired state (Low, High, Toggle)
 */
void ct_gpio_WritePin(ct_gpio_port_t portx,
                      uint8_t        PinMask,
                      ct_gpio_sta_t  state);

/**
 * @brief Toggle the state of a specified GPIO port and pin.
 *
 * @param[in] portx      GPIO port
 * @param[in] PinMask    GPIO pin
 */
void ct_gpio_TogglePin(ct_gpio_port_t portx, uint8_t PinMask);

/**
 * @brief Extern Pin Interrupt
 * @param channel INT0 or INT1
 * @param mode pin interrupt trigger mode.Level or Edge
 * @param enable Enable or Disable
 * @return No return value
 * @note If the pin is configured as an output, the read value may represent the output state of the pin.
 */
void ct_gpio_ExInt_Enable(ct_gpio_Int_t           channel,
                          ct_gpio_irq_trip_mode_t mode,
                          ct_bool                 enable);

/**
 * @brief Reads the state of the specified GPIO port.
 * @param portx GPIO port.
 * @param PinMask GPIO pin.
 * @param trip pin interrupt trigger mode.
 * @return uint8_t The state of the port.
 * @note If the pin is configured as an output, the read value may represent the output state of the pin.
 */
void ct_gpio_irq_Enable(ct_gpio_port_t     portx,
                        uint8_t            PinMask,
                        ct_gpio_irq_trip_t trip);

/**
 * @brief Set the specified GPIO port and pin as Schmitt trigger mode.
 * @param[in] portx GPIO port
 * @param[in]  PinMask GPIO pin
 * @param[in] state Schmitt trigger state (Low, High)
 * @return No return value
 */
void ct_gpio_SchmittTrigger(ct_gpio_port_t    portx,
                            uint8_t           PinMask,
                            ct_gpio_Schmitt_t state);

#if 0
void ct_gpio_SetQuasi(ct_gpio_port_t portx, uint8_t PinMask);
void ct_gpio_SetInput(ct_gpio_port_t portx, uint8_t PinMask);
void ct_gpio_SetOutput(ct_gpio_port_t portx, uint8_t PinMask);
void ct_gpio_SetOpenDrain(ct_gpio_port_t portx, uint8_t PinMask);
//
void ct_gpio_PullUp_Enable(ct_gpio_port_t portx, uint8_t PinMask);
void ct_gpio_PullUp_Disable(ct_gpio_port_t portx, uint8_t PinMask);
void ct_gpio_PullDown_Enable(ct_gpio_port_t portx, uint8_t PinMask);
void ct_gpio_PullDown_Disable(ct_gpio_port_t portx, uint8_t PinMask);
#endif

/****************************************************************************/
#ifdef __cplusplus
}
#endif
/****************************************************************************/
#endif /* __CT_GPIO_H__ */
/****************************************************************************/

/****************************************************************************/
/*                                                                          */
/*  End of file.                                                            */
/*                                                                          */
/****************************************************************************/
